import numpy as np
import pandas as pd
from sklearn.naive_bayes import GaussianNB
from sklearn.naive_bayes import MultinomialNB
from sklearn.model_selection import GridSearchCV


def createdataset():
    dataSet = np.array(
        [[0, 2, 0, 0, 'N'],
         [0, 2, 0, 1, 'N'],
         [1, 2, 0, 0, 'Y'],
         [2, 1, 0, 0, 'Y'],
         [2, 0, 1, 0, 'Y'],
         [2, 0, 1, 1, 'N'],
         [1, 0, 1, 1, 'Y'],
         [0, 1, 0, 0, 'N'],
         [0, 0, 1, 0, 'Y'],
         [2, 1, 1, 0, 'Y'],
         [0, 1, 1, 1, 'Y'],
         [1, 1, 0, 1, 'Y'],
         [1, 2, 1, 0, 'Y'],
         [2, 1, 0, 1, 'N'], ]
    )
    labels = ['age',  'income',  'job',  'credit']
    return dataSet,  labels

# 高斯贝叶斯https://www.cnblogs.com/ISGuXing/p/13777895.html
ds1, lab = createdataset()
clf_Ga = GaussianNB()
clf_Ga.fit(ds1[:, 0:4], ds1[:, 4])
predictArr = [0, 2, 0, 1]
print("预测结果")
print(clf_Ga.predict([predictArr]))
print("样本为1类的概率")
print(clf_Ga.predict_proba([predictArr]))
print("样本为2类的概率")
print(clf_Ga.predict_log_proba([predictArr]))



# 多项式贝叶斯
"""
多项式朴素贝叶斯是先验为多项式分布的朴素贝叶斯。 它假设特征是由一个简单多项式分布生成的。 
多项分布可以描述各种类型样本出现次数的概率，因此多项式朴素贝叶斯非常适合用于描述出现次数的特征。 
该模型常用于文本分类，特征表示的是次数，例如某个词语的出现次数。
"""

"""
这里使用GridSearchCV函数进行网格搜索交叉检验调参，评估模型的分数为accuracy即准确率。
调整的参数分别为：alpha（常数λ \lambdaλ），fit_prior（是否考虑先验概率）
"""

clf_Mu = MultinomialNB()

param_grid = [{'alpha':np.arange(0.9,1.1,0.1),
              'fit_prior':['True','False']}]
grid_search = GridSearchCV(clf_Mu, param_grid, cv=3, scoring='accuracy', return_train_score=True)
grid_search.fit(ds1[:, 0:4], ds1[:, 4])
# 输出最优参
print(grid_search.best_params_)

# 查看网格搜索模型分数
cvres = grid_search.cv_results_
for accuracy,params in zip(cvres["mean_test_score"], cvres["params"]):
    print("{:.2}".format(accuracy),params)

# 预测结果
final_model = grid_search.best_estimator_
X_test = np.array([predictArr])
X_test_prepared = final_model.predict(X_test)
print("预测结果")
print(X_test_prepared)
